// map.hpp
//

#ifndef _MAP_HPP
#define _MAP_HPP

#include "base.hpp"



// ZMap
//
class ZMap
{
public:
  ZMap ( int width,
         int height );

  int get_width () const { return width; }
  int get_height () const { return height; }
  float get_z (int x, int y) { return cells[y][x]; }
  
  void swap ( ZMap &other );
  void randomize ( float max_height );
  void smooth ( int passes );
  void level ( float lvl=0.f );
  
private:
  int width;
  int height;
  std::vector<std::vector<float>> cells;
};



// MapCell
//
struct MapCell
{
  float altitude{};
  glm::vec3 normal{};
  glm::vec3 smooth_normal{};
};



// Map
//
class Map
{
public:
  Map ();

  int get_width () const { return width; }
  int get_height () const { return height; }

  void apply_zmap ( ZMap &zmap );
  void update_normals ();
  void update_normal_flat ( int x,
                            int y );
  void smooth_normals ();
  void get_cell_normals ( int x,
                          int y,
                          glm::vec3 *normals );
  void create_mesh ( wgl::Mesh &mesh );
  void create_grid_mesh ( wgl::Mesh &mesh,
                          glm::vec3 color );
  
private:
  int width;
  int height;
  int stride;
  std::vector<MapCell> raw_cells;
  std::vector<MapCell *> cells;
};



#endif
